#ifndef __BOOTLOADER_H
#define __BOOTLOADER_H

#include "fmc.h"
#include "stdint.h"

#define SYS_INFO_MCU_MODEL			"GD32F103C8T6"														/* MCU型号 */
#define SYS_INFO_MCU_SRAM			"20KB"																/* SRAM大小 */
#define SYS_INFO_MCU_Hz				"108 MHz"															/* 系统最大频率 */
#define SYS_INFO_FLASH_SIZE			"64KB + 8MB"														/* FLASH大小 */
#define SYS_INFO_EEPROM_SIZE		"256Byte"															/* 片外EEPROM大小 */
#define SYS_INFO_NET_MODULE			"WH-GM5 LTE Cat-1"													/* 4G模块 */

/* flash分区 */
#define GD_FLASH_B_PAGE_NUM			20																	/* B区页数 */
#define GD_FLASH_A_PAGE_NUM			(GD_FLASH_PAGE_NUM - GD_FLASH_B_PAGE_NUM)							/* A区页数 */
#define GD_FLASH_A_BASE_PAGE		GD_FLASH_B_PAGE_NUM													/* A区起始页 */
#define GD_FLASH_A_BASE_ADDR		(GD_FLASH_BASE_ADDR + GD_FLASH_PAGE_SIZE * GD_FLASH_A_BASE_PAGE)	/* A区起始页地址 */

#define OTA_EVENT_FLAG_SET			0x00000001															/* OTA事件标志置位 */
#define OTA_EVENT_FLAG_CLR			0x00000000															/* OTA事件标志清除 */

/* OTA */
typedef struct {
	uint32_t ota_event_flag;																			/* OTA事件标志 */
	uint32_t ota_fire_lenth;																			/* OTA固件大小 */
	char ota_fire_version[10];																			/* OTA固件版本 */
} ota_info_struct;

#define OTA_INFO_STRUCT_SIZE		sizeof(ota_info_struct)												/* OTA结构体长度 */
	
/* 固件更新 */
typedef struct {
	uint8_t update_buff[GD_FLASH_PAGE_SIZE];															/* 数据缓存 */
	uint32_t W25Q64_block_num;																			/* 固件在块中编号 */
	uint32_t Xmodem_timer;																				/* Xmodem协议定时累加器 */
	uint32_t Xmodem_package_num;																		/* Xmodem协议接收到的数据包数量 */
	uint32_t Xmodem_CRC;																				/* Xmodem协议数据包CRC校验值 */
} update_zone_struct;
	
typedef enum {
	BOOT_FLAG_APP_START_FAILED		= 0,																/* APP跳转失败标志 */
	BOOT_FLAG_IAP_XMODEMC,																				/* Xmodem协议发送起始信号标志 */
	BOOT_FLAG_IAP_XMODEMD,																				/* Xmodem协议发送数据标志 */
} boot_flag_enum;

typedef void (*jump_func)(void);																		/* 函数指针重定义 */
typedef int (*cmd_callback_func)(void);																	/* 命令回调函数指针重定义 */

#define CMD_LIST_SIZE				6																	/* 命令个数 */

typedef struct {
	char *cmd_name;																						/* 命令名称 */
	int (*cmd_callback)(void);																			/* 命令回调函数指针 */
} cmd_info_struct;

typedef struct {
	int cmd_index;																						/* 命令索引 */
	cmd_info_struct	boot_cmd[CMD_LIST_SIZE];															/* 命令列表 */
} cmd_list_struct;

void bootloader_ota_event_flag_read(void);
void bootloader_ota_event_flag_save(void);
int bootloader_system_reset_callback(void);
int bootloader_erase_zone_callback(void);
int bootloader_IAP_download_callback(void);
int bootloader_version_set_callback(void);
int bootloader_version_get_callback(void);
uint16_t Xmodem_CRC16(uint8_t *data, uint16_t data_len);
void Xmodem_start_signal(void);
void bootloader_jump_to_app(uint32_t app_addr);
void bootloader_init(void);
void bootloader_system_info(void);
void bootloader_cmdline_info(void);
uint8_t bootloader_cmdline_enter(uint8_t timeout);
void bootloader_brance(void);	
void bootloader_cmd_parser(char *cmd_buff);
int bootloader_cmd_exec(void);
void bootloader_cmdline_loop(void);																	

#endif
